from duetopia.metadata.base import *
from mx.DateTime import DateTimeFrom
from RDF import SPARQLQuery

class RDF(Metadata):
    def export(self,file=file,template='metadata/rdf.xml'):
        """
        >>> d = Dataset()
        >>> md = RDF()
        >>> md.dataset = d   
        >>> rdf = md.export()
        """
        context = { 'dataset' : self.dataset,
                    'extents' : self.extents,
                    'datasource': self.datasource,
                    'agent':self.agent, }
        c = Context(context)
        t = loader.get_template(template)
        xml = t.render(c)
        return xml

def coordinates_wkt(polystr):
    """
    Helper function. Probably does not belong here. Returns WKT
    content for a list of coordinates, one per line.
    """
    def _f():
        for line in str(polystr).split('\n'):
            point = line.strip().replace(' ', '').replace(',', ' ')
            if point:
                yield point
    polygon = '(' + ', '.join(list(_f())) + ')'
    return polygon

def rdf_get_dataset(model, resource):
    """
    Return a dictionary representation of the dataset
    referred to by the given resource.
    """
    assert(resource.is_resource())

    dataset = {}
    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT DISTINCT ?title {
    <%s> dc:title ?title
}
""" % (resource.uri)
    for r in SPARQLQuery(q).execute(model):
        dataset["title"] = str(r["title"])
    return { 'dataset' : dataset }

def rdf_get_geometry(model, identifier):
    attrs = {}
    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX space: <http://sweet.jpl.nasa.gov/1.1/space.owl#>
PREFIX earthrealm: <http://sweet.jpl.nasa.gov/1.1/earthrealm.owl#>
SELECT DISTINCT ?polygon {
	_:resource dc:identifier '%s' .
	_:resource earthrealm:SurfaceRegion _:region .
	_:region space:Polygon ?polygon
}
""" % (identifier)
    polygons = []
    for r in SPARQLQuery(q).execute(model):
        polygons.append('(' + coordinates_wkt(r["polygon"]) + ')')
    if polygons:
        multi = 'MULTIPOLYGON(' + ', '.join(polygons) + ')'
        attrs["region"] = multi
    return attrs

def rdf_get_datasource(model, identifier):
    """
    Get more descriptive information about the datasource
    with the given identifier.
    """
    attrs = { 'identifier' : identifier }
    
    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX data: <http://sweet.jpl.nasa.gov/1.1/data.owl#>
SELECT DISTINCT ?res {
        ?res dc:identifier '%s' .
}
""" % (identifier)
    for r in SPARQLQuery(q).execute(model):
        attrs["uri"] = str(r["res"].uri)

    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX data: <http://sweet.jpl.nasa.gov/1.1/data.owl#>
SELECT DISTINCT ?format {
        _:resource dc:identifier '%s' .
        _:resource data:FileFormat ?format
}
""" % (identifier)
    for r in SPARQLQuery(q).execute(model):
        attrs["format"] = str(r["format"])

    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX time: <http://sweet.jpl.nasa.gov/1.1/time.owl#>
SELECT DISTINCT ?start, ?end {
        _:resource dc:identifier '%s' .
        _:resource time:Start ?start .
        _:resource time:End ?end
}
""" % (identifier)
    for r in SPARQLQuery(q).execute(model):
        attrs["start"] = DateTimeFrom(str(r["start"]))
        attrs["end"] = DateTimeFrom(str(r["end"]))

    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT DISTINCT ?title {
	_:resource dc:identifier '%s' .
        _:resource dc:title ?title
}
""" % (identifier)
    for r in SPARQLQuery(q).execute(model):
        attrs["title"] = str(r["title"])

    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX data: <http://sweet.jpl.nasa.gov/1.1/data.owl#>
SELECT DISTINCT ?dataset {
        _:resource dc:identifier '%s' .
        _:resource data:DataProduct ?dataset
}
""" % (identifier)
    for r in SPARQLQuery(q).execute(model):
        attrs.update(rdf_get_dataset(model, r["dataset"]))

    attrs.update(rdf_get_geometry(model, identifier))
    return attrs

def rdf_get_datasources(model):
    """
    Return a descriptive dictionary for each datasource present
    in the given model. A datasource is recognized by having an
    identifier (dc:identifier) and a type of (data:Dataset)
    """
    q = """
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX data: <http://sweet.jpl.nasa.gov/1.1/data.owl#>
SELECT DISTINCT ?identifier {
	_:resource dc:identifier ?identifier
}
"""
    for r in SPARQLQuery(q).execute(model):
         yield rdf_get_datasource(model, r["identifier"])
                
